package valuer

import (
	"database/sql"
	"orm/internal/errs"
	"orm/model"
	"reflect"
	"unsafe"
)

type unsafeValue struct {
	model *model.Model
	// 起始地址
	address unsafe.Pointer
}

var _ Creator = NewUnsafeValue

func NewUnsafeValue(model *model.Model, val any) Value {
	return unsafeValue{
		model:   model,
		address: reflect.ValueOf(val).UnsafePointer(),
	}
}

func (u unsafeValue) Field(name string) (any, error) {
	fd, ok := u.model.FieldsMap[name]
	if !ok {
		return nil, errs.NewErrUnknownField(name)
	}
	// 起始地址+偏移量
	fdAddress := unsafe.Pointer(uintptr(u.address) + fd.Offset)
	val := reflect.NewAt(fd.Type, fdAddress)
	return val.Elem().Interface(), nil
}

func (u unsafeValue) SetColumns(rows *sql.Rows) error {
	// 在这里，继续处理结果集
	// 获取有哪些列

	cs, err := rows.Columns()
	if err != nil {
		return err
	}
	var vals []any
	// 起始地址
	for _, c := range cs {
		// c 是列明
		fd, ok := u.model.ColumnMap[c]
		if !ok {
			return errs.NewErrUnknownColumn(c)
		}
		// 起始地址+偏移量
		fdAddress := unsafe.Pointer(uintptr(u.address) + fd.Offset)
		val := reflect.NewAt(fd.Type, fdAddress)
		// 反射在特定的地址上，创建一个特定类型的实例
		// 这里创建的实例是原本类型的指针类型
		// 例如fd.Type = int, 那么val是*int
		vals = append(vals, val.Interface())
	}
	err = rows.Scan(vals...)
	return nil
}
